package com.wywah.yunduo.security.supports.client;

import com.wywah.yunduo.security.utils.ClientUtils;
import com.wywah.yunduo.security.utils.OAuth2EndpointUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.lang.Nullable;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken;
import org.springframework.security.web.authentication.AuthenticationConverter;
import org.springframework.util.StringUtils;

import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * 自定义 ClientSecretBasic 客户端认证
 * @see org.springframework.security.oauth2.server.authorization.web.authentication.ClientSecretBasicAuthenticationConverter
 */
public class YunduoClientSecretBasicAuthenticationConverter implements AuthenticationConverter {

    @Override
    @Nullable
    public Authentication convert(HttpServletRequest request) {
        String header = request.getHeader(ClientUtils.CLIENG_BASICE_HEADER);
        if (header == null) {
            return null;
        } else {
            String[] parts = header.split("\\s");
            if (!parts[0].equalsIgnoreCase("Basic")) {
                return null;
            } else if (parts.length != 2) {
                throw new OAuth2AuthenticationException("invalid_request");
            } else {
                byte[] decodedCredentials;
                try {
                    decodedCredentials = Base64.getDecoder().decode(parts[1].getBytes(StandardCharsets.UTF_8));
                } catch (IllegalArgumentException var11) {
                    IllegalArgumentException ex = var11;
                    throw new OAuth2AuthenticationException(new OAuth2Error("invalid_request"), ex);
                }

                String credentialsString = new String(decodedCredentials, StandardCharsets.UTF_8);
                String[] credentials = credentialsString.split(":", 2);
                if (credentials.length == 2 && StringUtils.hasText(credentials[0]) && StringUtils.hasText(credentials[1])) {
                    String clientID;
                    String clientSecret;
                    try {
                        clientID = URLDecoder.decode(credentials[0], StandardCharsets.UTF_8);
                        clientSecret = URLDecoder.decode(credentials[1], StandardCharsets.UTF_8);
                    } catch (Exception var10) {
                        Exception ex = var10;
                        throw new OAuth2AuthenticationException(new OAuth2Error("invalid_request"), ex);
                    }

//                    return new YunduoOAuth2ClientSecretBasicAuthenticationToken(clientID, YunduoClientAuthenticationMethod.CUSTOM_CLIENT_SECRET_BASIC, clientSecret, OAuth2EndpointUtils.getParametersIfMatchesAuthorizationCodeGrantRequest(request, new String[0]));
                    return new OAuth2ClientAuthenticationToken(clientID, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, clientSecret, OAuth2EndpointUtils.getParametersIfMatchesAuthorizationCodeGrantRequest(request, new String[0]));
                } else {
                    throw new OAuth2AuthenticationException("invalid_request");
                }
            }
        }
    }
}
